package com.hydra.framework.router.interceptor;

import android.util.Log;
import androidx.annotation.NonNull;
import com.hydra.framework.router.RouterIntent;
import com.hydra.framework.util.StringUtil;

import java.util.Comparator;

import static com.hydra.framework.router.JRouter.JROUTER_LOG_TAG;

/**
 * Created by Hydra on 2017/8/3.
 *
 */
public final class RouterInterceptor {

    public static Comparator<RouterInterceptor> sRouterInterceptorComparator = new Comparator<RouterInterceptor>() {
        @Override
        public int compare(RouterInterceptor lhs, RouterInterceptor rhs) {
            if (!lhs.mUrl.equals(rhs.mUrl)) {
                throw new IllegalArgumentException("only the same url can be compared");
            }

            if(lhs.mInterceptorHashCode == rhs.mInterceptorHashCode) {
                return 0;
            }

            return (rhs.mPriority > lhs.mPriority) ? 1 : (rhs.mPriority < lhs.mPriority ? -1
                    : (rhs.mInterceptorHashCode > lhs.mInterceptorHashCode ? 1
                    : (rhs.mInterceptorHashCode < lhs.mInterceptorHashCode ? -1 : 0)));
        }
    };

    private final int mPriority;
    private final IRouterInterceptor mInterceptor;
    private final int mInterceptorHashCode;
    private final String mUrl;

    public RouterInterceptor(String url, @NonNull IRouterInterceptor interceptor, int priority) {
        this.mPriority = priority;
        this.mInterceptor = interceptor;
        this.mUrl = url;

        mInterceptorHashCode = StringUtil.combineStr(interceptor.getClass(), "::", mUrl, "::",
                System.identityHashCode(interceptor)).hashCode();
    }

    public boolean intercept(RouterIntent routerIntent) {
        try {
            return mInterceptor.onIntercept(routerIntent);
        } catch (Throwable e) {
            Log.e(JROUTER_LOG_TAG, "intercept router intent failed : " + e.toString());

            return false;
        }
    }

    @Override
    public boolean equals(Object obj) {
        if(obj == null || !(obj instanceof RouterInterceptor)) {
            return false;
        }

        RouterInterceptor other = (RouterInterceptor) obj;

        return this.mUrl.equals(other.mUrl) && this.mInterceptorHashCode == other.mInterceptorHashCode;
    }

    IRouterInterceptor interceptor() {
        return mInterceptor;
    }

    @Override
    public int hashCode() {
        return mInterceptorHashCode;
    }
}
